home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / Movie3.0 / Source / xanim / xanim_gif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-02  |  15.9 KB  |  657 lines

  1.  
  2. /*
  3.  * xanim_gif.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992,1993,1994 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include "xanim_gif.h"
  19.  
  20. ULONG GIF_Read_Anim();
  21. GIF_FRAME *GIF_Read_File();
  22. GIF_FRAME *GIF_Add_Frame();
  23.  
  24. LONG Is_GIF_File();
  25. void GIF_Decompress();
  26. void GIF_Get_Next_Entry();
  27. void GIF_Add_To_Table();
  28. void GIF_Send_Data();
  29. void GIF_Init_Table();
  30. void GIF_Clear_Table();
  31. ULONG GIF_Get_Code();
  32. void GIF_Screen_Header();
  33. void GIF_Image_Header();
  34. void GIF_Read_Extension();
  35.  
  36. XA_ACTION *ACT_Get_Action();
  37. XA_CHDR   *ACT_Get_CMAP();
  38. void ACT_Setup_PIXMAP();
  39. void ACT_Setup_IMAGE();
  40. void ACT_Setup_CLIP();
  41. void ACT_Setup_Mapped();
  42. void ACT_Add_CHDR_To_Action();
  43. LONG UTIL_Get_LSB_Short();
  44.  
  45.  
  46. #define MAXVAL  4100            /* maxval of lzw coding size */
  47. #define MAXVALP 4200
  48.  
  49.  
  50. #define GIF_CMAP_SIZE 256
  51. static GIF_Screen_Hdr gifscrn;
  52. static GIF_Image_Hdr gifimage;
  53. static ColorReg gif_cmap[GIF_CMAP_SIZE];
  54. static XA_CHDR *gif_chdr_now;
  55. static GIF_Table table[MAXVALP];
  56.  
  57. static ULONG root_code_size,code_size,CLEAR,EOI,INCSIZE;
  58. static ULONG nextab;
  59. static ULONG gif_mask[16] = {1,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,0,0};
  60. static ULONG gif_ptwo[16] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,0,0};
  61. static UBYTE gif_buff[MAXVALP];
  62. static ULONG gif_block_size;
  63. static LONG gif_bits,num_bits;
  64. static gif_lace_flag;
  65.  
  66. static LONG gif_max_imagec,gif_max_imagex,gif_max_imagey,gif_max_imaged;
  67. static ULONG gif_imagex,gif_imagey,gif_imagec,gif_imaged;
  68. static ULONG gif_screenx,gif_screeny;
  69.  
  70. static LONG pic_i,pic_size;
  71.  
  72. /* GIF89a variables */
  73. static LONG gif_anim_type;  /* from GIF89 f9 extension */
  74. static LONG gif_anim_time;  /* from GIF89 f9 extension */
  75. static LONG gif_anim_mask;  /* from GIF89 f9 extension */
  76.  
  77. static GIF_FRAME *gif_frame_start,*gif_frame_cur;
  78. static ULONG gif_frame_cnt;
  79.  
  80. GIF_FRAME *GIF_Add_Frame(time,act)
  81. ULONG time;
  82. XA_ACTION *act;
  83. {
  84.   GIF_FRAME *gframe;
  85.  
  86.   gframe = (GIF_FRAME *) malloc(sizeof(GIF_FRAME));
  87.   if (gframe == 0) TheEnd1("GIF_Add_Frame: malloc err");
  88.  
  89.   gframe->time = time;
  90.   gframe->act = act;
  91.   gframe->next = 0;
  92.  
  93.   if (gif_frame_start == 0) gif_frame_start = gframe;
  94.   else gif_frame_cur->next = gframe;
  95.  
  96.   gif_frame_cur = gframe;
  97.   gif_frame_cnt++;
  98.   return(gframe);
  99. }
  100.  
  101. void
  102. GIF_Free_Frame_List(gframes)
  103. GIF_FRAME *gframes;
  104. {
  105.   GIF_FRAME *gtmp;
  106.   while(gframes != 0)
  107.   {
  108.     gtmp = gframes;
  109.     gframes = gframes->next;
  110.     FREE(gtmp,0x3000);
  111.   }
  112. }
  113.  
  114. ULONG
  115. GIF_Read_Anim(fname,anim_hdr)
  116. char *fname;
  117. XA_ANIM_HDR *anim_hdr;
  118. {
  119.   GIF_FRAME *glist,*gtmp;
  120.   ULONG frame_cnt,i;
  121.  
  122.   glist = GIF_Read_File(fname,anim_hdr,&frame_cnt);
  123.   if (glist==0) return(FALSE);
  124.  
  125.   anim_hdr->frame_lst = (XA_FRAME *)malloc(sizeof(XA_FRAME) * (frame_cnt+1));
  126.   if (anim_hdr->frame_lst == NULL)
  127.        TheEnd1("GIF_Read_Anim: malloc err");
  128.  
  129.   gtmp = glist;
  130.   i = 0;
  131.   while(gtmp != 0)
  132.   {
  133.     if (i >= frame_cnt)
  134.     {
  135.       fprintf(stderr,"GIF_Read_Anim: frame inconsistency %ld %ld\n",
  136.         i,frame_cnt);
  137.       break;
  138.     }
  139.     anim_hdr->frame_lst[i].time = gtmp->time;
  140.     anim_hdr->frame_lst[i].act = gtmp->act;
  141.     gtmp = gtmp->next;
  142.     i++;
  143.   }
  144.   anim_hdr->frame_lst[i].time = 0;
  145.   anim_hdr->frame_lst[i].act  = 0;
  146.   anim_hdr->loop_frame = 0;
  147.   if (i > 0) anim_hdr->last_frame = i - 1;
  148.   else i = 0;
  149.  
  150.   GIF_Free_Frame_List(glist);
  151.   return(TRUE);
  152. }
  153.  
  154. /*
  155.  *
  156.  */
  157. GIF_FRAME *GIF_Read_File(fname,anim_hdr,frame_cnt)
  158. char *fname;
  159. XA_ANIM_HDR *anim_hdr;
  160. ULONG *frame_cnt;
  161. {
  162.   FILE *fp;
  163.   LONG i,exit_flag;
  164.   XA_ACTION *act;
  165.  
  166.   gif_frame_cnt = 0;
  167.   gif_frame_start = gif_frame_cur = 0;
  168.   gif_imagex = gif_max_imagex = 0;
  169.   gif_imagey = gif_max_imagey = 0;
  170.   gif_imagec = gif_max_imagec = 0;
  171.   gif_imaged = gif_max_imaged = 0;
  172.   gif_screenx = 0;
  173.   gif_screeny = 0;
  174.  
  175.   if ( (fp=fopen(fname,XA_OPEN_MODE))==0)
  176.   { 
  177.     fprintf(stderr,"Can't open %s for reading.\n",fname); 
  178.     return(0);
  179.   }
  180.  
  181.   gif_anim_type = 0;
  182.   gif_anim_time = XA_GET_TIME(MS_PER_60HZ);
  183.   gif_anim_mask = 0;
  184.  
  185.   GIF_Screen_Header(fp,anim_hdr);
  186.  
  187.   /*** read until  ,  separator */
  188.   do
  189.   {
  190.     i=fgetc(fp);
  191.     if ( (i<0) && feof(fp))
  192.     {
  193.       fclose(fp);
  194.       fprintf(stderr,"GIF_Read_Header: Unexpected EOF\n");
  195.       return(0);
  196.     }
  197.     if (i == '!') GIF_Read_Extension(fp);  /* GIF extension */
  198.   } while(i != ',');
  199.  
  200.   exit_flag = 0;
  201.   while(!exit_flag)
  202.   {
  203.     UBYTE *pic_ptr;
  204.   
  205.     /* Read Image Header
  206.      */
  207.     GIF_Image_Header(fp,anim_hdr);
  208.  
  209.     /*** Setup ACTION for IMAGE or CLIP */
  210.     act = ACT_Get_Action(anim_hdr);
  211.  
  212.     pic_size = gif_imagex * gif_imagey;
  213.  
  214.     pic_ptr = (UBYTE *) malloc( XA_PIC_SIZE(pic_size) );
  215.     if (pic_ptr==0) TheEnd1("GIF_Read_File: could malloc of image\n");
  216.  
  217.     pic_i=0;
  218.     GIF_Decompress(fp,pic_ptr);
  219.  
  220.     if (gif_anim_type == 0x01)
  221.     {
  222.       ACT_Setup_Mapped(act, pic_ptr, gif_chdr_now,
  223.             gifimage.left,gifimage.top,gif_imagex,gif_imagey,
  224.             gif_screenx,gif_screeny,TRUE,gif_anim_mask,
  225.             TRUE,FALSE,FALSE);
  226.     }
  227.     else
  228.     {
  229.        ACT_Setup_Mapped(act, pic_ptr, gif_chdr_now,
  230.             gifimage.left,gifimage.top,gif_imagex,gif_imagey,
  231.             gif_screenx,gif_screeny,FALSE,0,TRUE,FALSE,FALSE);
  232.     }
  233.     ACT_Add_CHDR_To_Action(act,gif_chdr_now);
  234.     GIF_Add_Frame(gif_anim_time,act);
  235.  
  236.     /*** read until "," ";" or feof */ 
  237.     do
  238.     {
  239.       i=fgetc(fp);
  240.       if ( (i<0) || (i == ';')) exit_flag = 1;
  241.       else if (i == '!') GIF_Read_Extension(fp);  /* extension */
  242.     } while( (i != ',') && (!exit_flag) );
  243.  
  244.   } /*** end of while images */
  245.   fclose(fp);
  246.  
  247.   anim_hdr->imagex = gif_max_imagex;
  248.   anim_hdr->imagey = gif_max_imagey;
  249.   anim_hdr->imagec = gif_max_imagec;
  250.   anim_hdr->imaged = gif_max_imaged;
  251.   *frame_cnt = gif_frame_cnt;
  252.   return(gif_frame_start);
  253. }
  254.  
  255. void GIF_Decompress(fp,pic)
  256. FILE *fp;
  257. char *pic;
  258. {
  259.   register ULONG code,old;
  260.  
  261.   gif_bits = 0;
  262.   num_bits=0;
  263.   gif_block_size=0;
  264.      /* starting code size of LZW */
  265.   root_code_size=(fgetc(fp) & 0xff); 
  266.   DEBUG_LEVEL3 fprintf(stderr,"  root code size = %ld\n",root_code_size);
  267.   GIF_Clear_Table();  /* clear decoding symbol table */
  268.  
  269.   code=GIF_Get_Code(fp);
  270.  
  271.   if (code==CLEAR) 
  272.   {
  273.     GIF_Clear_Table(); 
  274.     code=GIF_Get_Code(fp);
  275.   }
  276.   /* write code(or what it currently stands for) to file */
  277.   GIF_Send_Data(code,pic);   
  278.   old=code;
  279.   code=GIF_Get_Code(fp);
  280.   do
  281.   {
  282.     if (table[code].valid == 1)    /* if known code */
  283.     {
  284.        /* send it's associated string to file */
  285.       GIF_Send_Data(code,pic);
  286.       GIF_Get_Next_Entry(fp);       /* get next table entry (nextab) */
  287.       GIF_Add_To_Table(old,code,nextab);  /* add old+code to table */
  288.       old=code;
  289.     }
  290.     else      /* code doesn't exist */
  291.     {
  292.       GIF_Add_To_Table(old,old,code);   /* add old+old to table */
  293.       GIF_Send_Data(code,pic);
  294.       old=code;
  295.     }
  296.     code=GIF_Get_Code(fp);
  297.     if (code==CLEAR)
  298.     { 
  299.       GIF_Clear_Table();
  300.       code=GIF_Get_Code(fp);
  301.       GIF_Send_Data(code,pic);
  302.       old=code;
  303.       code=GIF_Get_Code(fp);
  304.     }
  305.   } while(code!=EOI);
  306. }
  307.  
  308. void GIF_Get_Next_Entry(fp)
  309. FILE *fp;
  310. {
  311.     /* table walk to empty spot */
  312.   while( (table[nextab].valid==1) && (nextab<MAXVAL) ) nextab++;
  313.  
  314.   /* Ran out of space??  Something's roached */
  315.   if (nextab>=MAXVAL)    
  316.   { 
  317.     fprintf(stderr,"Error: GetNext nextab=%ld\n",nextab);
  318.     fclose(fp);
  319.     TheEnd();
  320.   }
  321.   if (nextab == INCSIZE)   /* go to next table size (and LZW code size ) */
  322.   {
  323.     DEBUG_LEVEL4 fprintf(stderr,"GetNext INCSIZE was %ld ",nextab);
  324.     code_size++; INCSIZE=(INCSIZE*2)+1;
  325.     if (code_size>=12) code_size=12;
  326.     DEBUG_LEVEL4 fprintf(stderr,"<%ld>",INCSIZE);
  327.   }
  328. }
  329.  
  330.  
  331. /*  body is associated string
  332.  *  next is code to add to that string to form associated string for
  333.  *  index
  334.  */     
  335. void GIF_Add_To_Table(body,next,index)
  336. register ULONG body,next,index;
  337. {
  338.   if (index>MAXVAL)
  339.   { 
  340.     fprintf(stderr,"Error index=%ld\n",index);
  341.   }
  342.   else
  343.   {
  344.     table[index].valid=1;
  345.     table[index].data=table[next].first;
  346.     table[index].first=table[body].first;
  347.     table[index].last=body;
  348.   }
  349. }
  350.  
  351. void GIF_Send_Data(index,pic)
  352. register LONG index;
  353. char *pic;
  354. {
  355.   register LONG i,j;
  356.   i=0;
  357.   do         /* table walk to retrieve string associated with index */
  358.   { 
  359.     gif_buff[i] = table[index].data; 
  360.     i++;
  361.     index = table[index].last;
  362.     if (i>MAXVAL)
  363.     { 
  364.       fprintf(stderr,"Error: Sending i=%ld index=%ld\n",i,index);
  365.       TheEnd();
  366.     }
  367.   } while(index >= 0);
  368.  
  369.   /* now invert that string since we retreived it backwards */
  370.   i--;
  371.   for(j=i;j>=0;j--) 
  372.   {
  373.     if (pic_i < pic_size) pic[pic_i++] = gif_buff[j];
  374.     else fprintf(stderr,"GIF_Send: data beyond image size - ignored\n");
  375.     if (gif_lace_flag)
  376.     {
  377.       if ((pic_i % gif_imagex) == 0 )
  378.       { 
  379.         switch(gif_lace_flag)
  380.         {
  381.           case 1: pic_i += gif_imagex * 7; break; /* fill every 8th row */
  382.           case 2: pic_i += gif_imagex * 7; break; /* fill every 8th row */
  383.           case 3: pic_i += gif_imagex * 3; break; /* fill every 4th row */
  384.           case 4: pic_i += gif_imagex    ; break; /* fill every other row */
  385.         }
  386.       }
  387.       if (pic_i >= pic_size)
  388.       {
  389.         gif_lace_flag++;
  390.         switch(gif_lace_flag)
  391.         {
  392.           case 2: pic_i = gif_imagex << 2; break;  /* start at 4th row */
  393.           case 3: pic_i = gif_imagex << 1; break;  /* start at 2nd row */
  394.           case 4: pic_i = gif_imagex;      break;  /* start at 1st row */
  395.           default: gif_lace_flag = 0; pic_i = 0; break;
  396.         }
  397.       }
  398.     } /*** end of if gif_lace_flag */
  399.   } /*** end of code expansion */
  400. }
  401.  
  402.  
  403. /* 
  404.  * initialize string table 
  405.  */
  406. void GIF_Init_Table()       
  407. {
  408.   register LONG maxi,i;
  409.  
  410.   DEBUG_LEVEL3 fprintf(stderr,"  Initing Table...");
  411.   maxi=gif_ptwo[root_code_size];
  412.   for(i=0; i<maxi; i++)
  413.   {
  414.     table[i].data=i;   
  415.     table[i].first=i;
  416.     table[i].valid=1;  
  417.     table[i].last = -1;
  418.   }
  419.   CLEAR=maxi; 
  420.   EOI=maxi+1; 
  421.   nextab=maxi+2;
  422.   INCSIZE = (2*maxi)-1;
  423.   code_size=root_code_size+1;
  424.   DEBUG_LEVEL3 fprintf(stderr,"done\n");
  425. }
  426.  
  427.  
  428. /* 
  429.  * clear table 
  430.  */
  431. void GIF_Clear_Table()   
  432. {
  433.  register LONG i;
  434. DEBUG_LEVEL3 fprintf(stderr,"  Clearing Table...\n");
  435.  for(i=0;i<MAXVAL;i++) table[i].valid=0;
  436.  GIF_Init_Table();
  437. }
  438.  
  439.  
  440. /*CODE*/
  441. ULONG GIF_Get_Code(fp) /* get code depending of current LZW code size */
  442. FILE *fp;
  443. {
  444.   ULONG code;
  445.   register LONG tmp;
  446.  
  447.   while(num_bits < code_size)
  448.   {
  449.     /**** if at end of a block, start new block */
  450.     if (gif_block_size==0)
  451.     {
  452.       tmp = fgetc(fp);
  453.       if (tmp >= 0 ) gif_block_size=(ULONG)(tmp);
  454.       else TheEnd1("EOF in data stream\n");
  455.       DEBUG_LEVEL3 fprintf(stderr,"New Block size=%ld\n",gif_block_size);
  456.     }
  457.  
  458.     tmp = fgetc(fp);   gif_block_size--;
  459.     if (tmp >= 0)
  460.     {
  461.       gif_bits |= ( ((ULONG)(tmp) & (ULONG)(0xff)) << num_bits );
  462.       DEBUG_LEVEL3 
  463.        fprintf(stderr,"tmp=%lx bits=%lx num_bits=%ld\n",tmp,gif_bits,num_bits);
  464.  
  465.       num_bits+=8;
  466.     }
  467.     else TheEnd1("EOF in data stream\n");
  468.   }
  469.  
  470.   code = gif_bits & gif_mask[code_size];
  471.   gif_bits >>= code_size;  
  472.   num_bits -= code_size;
  473.   DEBUG_LEVEL3 fprintf(stderr,"code=%lx \n",code);
  474.  
  475.   if (code>MAXVAL)
  476.   {
  477.     fprintf(stderr,"\nError! in stream=%lx \n",code);
  478.     fprintf(stderr,"CLEAR=%lx INCSIZE=%lx EOI=%lx code_size=%lx \n",
  479.                                            CLEAR,INCSIZE,EOI,code_size);
  480.     code=EOI;
  481.   }
  482.  
  483.   if (code==INCSIZE)
  484.   {
  485.     DEBUG_LEVEL3 fprintf(stderr,"  code=INCSIZE(%ld)\n",INCSIZE);
  486.     if (code_size<12)
  487.     {
  488.       code_size++; INCSIZE=(INCSIZE*2)+1;
  489.     }
  490.     else DEBUG_LEVEL3 fprintf(stderr,"  <13?>\n");
  491.     DEBUG_LEVEL3 fprintf(stderr,"  new size = %ld\n",code_size);
  492.   }
  493.   return(code);
  494. }
  495.  
  496.  
  497. /* 
  498.  * read GIF header 
  499.  */
  500. void GIF_Screen_Header(fp,anim_hdr)
  501. FILE *fp;
  502. XA_ANIM_HDR *anim_hdr;
  503. {
  504.  LONG temp,i;
  505.  
  506.  for(i=0;i<6;i++) fgetc(fp);    /* read and toss GIF87a or GIF89? */
  507.  
  508.  gif_screenx = gif_imagex = gifscrn.width  = UTIL_Get_LSB_Short(fp);
  509.  gif_screeny = gif_imagey = gifscrn.height = UTIL_Get_LSB_Short(fp);
  510.  
  511.  temp=fgetc(fp);
  512.  gifscrn.m       =  temp & 0x80;
  513.  gifscrn.cres    = (temp & 0x70) >> 4;
  514.  gifscrn.pixbits =  temp & 0x07;
  515.  gifscrn.bc  = fgetc(fp);
  516.  temp=fgetc(fp);
  517.  gif_imaged = gifscrn.pixbits + 1;
  518.  gif_imagec = gif_ptwo[gif_imaged];
  519.  
  520.  if (gif_imagex > gif_max_imagex) gif_max_imagex = gif_imagex;
  521.  if (gif_imagey > gif_max_imagey) gif_max_imagey = gif_imagey;
  522.  if (gif_imagec > gif_max_imagec) gif_max_imagec = gif_imagec;
  523.  if (gif_imaged > gif_max_imaged) gif_max_imaged = gif_imaged;
  524.  
  525.  if (xa_verbose == TRUE)
  526.   fprintf(stderr,"  Screen: %ldx%ldx%ld m=%ld cres=%ld bkgnd=%ld pix=%ld\n",
  527.     gifscrn.width,gifscrn.height,gif_imagec,gifscrn.m,gifscrn.cres,
  528.     gifscrn.bc,gifscrn.pixbits);
  529.  
  530.  if (   (gif_imagec > x11_cmap_size) && (x11_cmap_flag == TRUE)
  531.      && (x11_display_type & XA_X11_CMAP) )
  532.  {
  533.   fprintf(stderr,"ERROR: Image has %ld colors, display can handle %ld\n",
  534.                     gif_imagec,x11_cmap_size);
  535.   TheEnd();
  536.  }
  537.  
  538.   if (gifscrn.m)
  539.   {
  540.      for(i=0; i < gif_imagec; i++)
  541.      {
  542.        gif_cmap[i].red   = fgetc(fp);
  543.        gif_cmap[i].green = fgetc(fp);
  544.        gif_cmap[i].blue  = fgetc(fp);
  545.      }
  546.  
  547.      gif_chdr_now = ACT_Get_CMAP(gif_cmap,gif_imagec,0,gif_imagec,0,8,8,8);
  548.   }
  549. } /* end of function */
  550.  
  551. /*
  552.  *
  553.  */
  554. void GIF_Image_Header(fp,anim_hdr)
  555. FILE *fp;
  556. XA_ANIM_HDR *anim_hdr;
  557. {
  558.  LONG temp,i;
  559.  
  560.  gifimage.left   = UTIL_Get_LSB_Short(fp);
  561.  gifimage.top    = UTIL_Get_LSB_Short(fp);
  562.  gifimage.width  = UTIL_Get_LSB_Short(fp);
  563.  gifimage.height = UTIL_Get_LSB_Short(fp);
  564.  temp=fgetc(fp);
  565.  gifimage.m        = temp & 0x80;
  566.  gifimage.i        = temp & 0x40;
  567.  if (gifimage.i) gif_lace_flag = 1;
  568.  else gif_lace_flag = 0;
  569.  gifimage.pixbits  = temp & 0x07;
  570.  gif_imaged = gifimage.pixbits + 1;
  571.  gif_imagex = gifimage.width;
  572.  gif_imagey = gifimage.height;
  573.  gif_imagec = gif_ptwo[gif_imaged];
  574.  
  575.  if (gif_imagex > gif_max_imagex) gif_max_imagex = gif_imagex;
  576.  if (gif_imagey > gif_max_imagey) gif_max_imagey = gif_imagey;
  577.  if (gif_imagec > gif_max_imagec) gif_max_imagec = gif_imagec;
  578.  if (gif_imaged > gif_max_imaged) gif_max_imaged = gif_imaged;
  579.  
  580.  DEBUG_LEVEL1
  581.  {
  582.   fprintf(stderr,"  Image: %ldx%ldx%ld m=%ld i=%ld pix=%ld resvd=%lx",
  583.     gif_imagex,gif_imagey,gif_imagec,gifimage.m,gifimage.i,gifimage.pixbits,
  584.     gifimage.reserved );
  585.   fprintf(stderr,"Pos: %ldx%ld \n",gifimage.left,gifimage.top);
  586.  }
  587.  
  588.    /* Read in Image CMAP if Image has one */
  589.   if (gifimage.m)
  590.   {
  591.     for(i=0; i < gif_imagec; i++)
  592.     {
  593.       gif_cmap[i].red   = fgetc(fp);
  594.       gif_cmap[i].green = fgetc(fp);
  595.       gif_cmap[i].blue  = fgetc(fp);
  596.     }
  597.     gif_chdr_now = ACT_Get_CMAP(gif_cmap,gif_imagec,0,gif_imagec,0,8,8,8);
  598.   }
  599. }
  600.  
  601. /*
  602.  *
  603.  */
  604. LONG Is_GIF_File(filename)
  605. char *filename;
  606. {
  607.  FILE *fp;
  608.  ULONG firstword;
  609.  
  610.  if ( (fp=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE);
  611.  /* by reading bytes we can ignore big/little endian problems */
  612.  firstword  = (ULONG)(fgetc(fp) & 0xff) << 24;
  613.  firstword |= (ULONG)(fgetc(fp) & 0xff) << 16;
  614.  firstword |= (ULONG)(fgetc(fp) & 0xff) <<  8;
  615.  firstword |= (ULONG)(fgetc(fp) & 0xff);
  616.  
  617.  fclose(fp);
  618.  
  619.  if (firstword == 0x47494638) return((LONG)TRUE);
  620.  return((LONG)FALSE);
  621. }
  622.  
  623. void
  624. GIF_Read_Extension(fp)
  625. FILE *fp;
  626. {
  627.   LONG block_size,code,tmp,i;
  628.  
  629.   code = fgetc(fp);
  630.   DEBUG_LEVEL2 fprintf(stderr,"  GIF Extension: Code = %lx\n",code);
  631.   if ( (code == 0xfe) && (xa_verbose==TRUE) )
  632.     fprintf(stderr,"  GIF COMMENT EXTENSION BLOCK\n");
  633.   block_size = fgetc(fp);
  634.  
  635.   if ( (code == 0xf9) && (block_size == 4))
  636.   {
  637.     gif_anim_type = fgetc(fp);
  638.     i = UTIL_Get_LSB_Short(fp); if (i < 0) i = 1;
  639.     gif_anim_time = XA_GET_TIME(i * 10);
  640.     gif_anim_mask = fgetc(fp);
  641.     block_size = fgetc(fp);
  642.   }
  643.  
  644.   while(block_size > 0)
  645.   {
  646.     for(i=0; i<block_size; i++) 
  647.     {
  648.       tmp=fgetc(fp);
  649.       if ( (code == 0xfe) && (xa_verbose==TRUE) ) fprintf(stderr,"%c",tmp);
  650.       if (code == 0xf9) DEBUG_LEVEL1 fprintf(stderr,"%lx ",tmp);
  651.     }
  652.     block_size = fgetc(fp);
  653.     if (code == 0xf9) DEBUG_LEVEL1 fprintf(stderr,"\n");
  654.   }
  655. }
  656.  
  657.